package com.hmjk.health.health;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.hmjk.health.HealthApp;
import com.hmjk.health.R;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.setting.SettingActivity;
import com.hmjk.health.util.DEV_DATA;
import com.hmjk.health.util.MULTI_USER_DEV_DATA;



//import com.hmjk.health.health.HealthCardsOverViewActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class HealthCardsActivity extends FragmentActivity implements OnClickListener, OnPageChangeListener{
	private final String TAG = HealthCardsActivity.class.getSimpleName();
	private HealthApp mApp = null;
	private MULTI_USER_DEV_DATA mCurAccount = null;
	private ProgressBar mLoadingProgress;
	private TextView mCardTitle;
	private ViewPager mSlider;
	private FragmentStatePagerAdapter mAdapter;
	private boolean loaded = false;
	private ArrayList<HealthCardFragment> mPages = new ArrayList<HealthCardFragment>();
	private HashMap<String, HealthCardFragment> mFragmentMap = new HashMap<String, HealthCardFragment>();
	private ArrayList<MULTI_USER_DEV_DATA> mAccountListData = new ArrayList<MULTI_USER_DEV_DATA>();
	
	
	
	private void logd(String info){
		Log.d(TAG,info);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		logd("onCreate");
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		mApp = (HealthApp)getApplication();
		
		Intent i = getIntent();
		
		String tid = i.getStringExtra("tid");
		String subcode = i.getStringExtra("subcode");
		mCurAccount = new MULTI_USER_DEV_DATA();
		if(tid != null){
			mCurAccount.id = tid.trim();
			mCurAccount.subcode = subcode.trim();
		}
		
		setContentView(R.layout.health_cards_activity);
		ImageView back = (ImageView) findViewById(R.id.back);
		back.setOnClickListener(this);
		
		ImageView set = (ImageView) findViewById(R.id.set);
		set.setOnClickListener(this);
		
		mLoadingProgress = (ProgressBar) findViewById(R.id.loading_progress);
		mLoadingProgress.setVisibility(View.GONE);
		
		mAdapter = new FragmentStatePagerAdapter(getSupportFragmentManager()){

			@Override
			public Fragment getItem(int pos) {
				return mPages.get(pos);
			}

			@Override
			public int getCount() {
				return mPages.size();
			}
			
			@Override
			public int getItemPosition(Object object){
				return PagerAdapter.POSITION_NONE;
			}
		};
		
		mSlider = (ViewPager) findViewById(R.id.slider_pager);
		mSlider.setAdapter(mAdapter);
		mSlider.setOnPageChangeListener(this);
		
		retrieveAccountListData();
		refreshDeviceSetting();
		loaded = false;
		
		mCardTitle = (TextView)findViewById(R.id.card_title);
		mCardTitle.setVisibility(View.INVISIBLE);
		
		buildCard();
	}
	
	public boolean refreshList(){
		long upTime = mApp.getDataManager().checkRequestTime(DataManager.F_DEVICESUBLIST);
		long curMs = System.currentTimeMillis();
		if((curMs - upTime) < 1000 * 60 * 1){
			return false;
		}
		return mApp.getDataManager().refreshData(DataManager.F_DEVICESUBLIST);
	}
	
	private void refreshAccountList(){
		HashMap<String,String> oldmap = new HashMap<String,String>();
		for(MULTI_USER_DEV_DATA d:mAccountListData){
			String key = d.id+"-"+d.subcode;
			oldmap.put(key, key);
		}
		
		retrieveAccountListData();
		refreshDeviceSetting();
		boolean updateAll = false;
		for(MULTI_USER_DEV_DATA d:mAccountListData){
			String key = d.id+"-"+d.subcode;
			String v = oldmap.get(key);
			if(v != null){
				oldmap.remove(key);
			}else{
				updateAll = true;
				break;
			}
		}
		
		if(updateAll){
			//new account found
			loaded = false;
			buildCard();
			startLoading();
		}else{
			if(oldmap.size() > 0){
				//one or more account deleted
				loaded = false;
				buildCard();
				startLoading();
			}else{
				updateFragments();
				mAdapter.notifyDataSetChanged();
			}
		}
	}
	
	private void updateFragments(){
		int size = mAccountListData.size();
		
		for(DEV_DATA d:mAccountListData){
			HealthCardFragment f = mFragmentMap.get(d.id);
			if(f != null){
				Bundle args = new Bundle();
				args.putInt("total", size);
				args.putSerializable("account", d);
				f.updateArgs(args);
			}
		}
	}
	
	
	private void retrieveAccountListData(){
		JSONObject devjson = (JSONObject) mApp.getDataManager().checkData(DataManager.F_DEVICELIST, null);
		if(devjson != null){
			try{
				JSONArray devar = devjson.getJSONArray("array");
				int devlen = devar.length();
				mAccountListData.clear();
				
				boolean foundsub = false;
				int index = 0;
				for(int i = 0; i < devlen; i++){
					JSONObject devone = devar.getJSONObject(i);
					String tid = devone.getString("tid");
					if((tid == null) || tid.trim().isEmpty()){
						continue;
					}
					String devtype = devone.getString("type");
					if(false == DEV_DATA.isHealthDev(devtype)){
						continue;
					}
					
					String devname = devone.getString("name");
					String ss = devone.getString("status");
					int devstatus = Integer.parseInt(ss);	
					String a = devone.getString("admin");
					int devadmin = Integer.parseInt(a);

					String[] args = new String[2];
					args[0] = "TID";
					args[1] = tid;
					JSONObject subinfo = (JSONObject) mApp.getDataManager().checkData(DataManager.F_DEVICESUBINFO,args);
					
					if(subinfo != null){
						JSONArray subar = subinfo.getJSONArray("array");
						int sublen = subar.length();
						if(sublen <= 0){
							MULTI_USER_DEV_DATA d = new MULTI_USER_DEV_DATA();
							/*dev data*/
							d.id = tid;
							d.name = devname;
							d.type = devtype;
							d.status = devstatus;
							d.admin = devadmin;
							d.index = index;
							mAccountListData.add(d);
							index ++;
							continue;
						}else{
							MULTI_USER_DEV_DATA[] temp = new MULTI_USER_DEV_DATA[sublen];
							for(int j = 0; j < sublen; j++){
								JSONObject subone = subar.getJSONObject(j);
								MULTI_USER_DEV_DATA d = new MULTI_USER_DEV_DATA();
								/*dev data*/
								d.id = subone.getString("tid");
								d.name = devname;
								d.type = devtype;
								d.status = devstatus;
								d.admin = devadmin;
								
								/*multi account data*/
								String scode = subone.getString("subcode");
								d.subcode = scode;
								d.nick = subone.getString("nickname");
								d.birthday = subone.getString("birthday");
								d.gender = subone.getString("gender");
								d.height = subone.getDouble("height");
								d.weight = subone.getDouble("weight");
								temp[j] = d;
							}
							Arrays.sort(temp,0,sublen,new Comparator<MULTI_USER_DEV_DATA>(){
								@Override
								public int compare(MULTI_USER_DEV_DATA arg0, MULTI_USER_DEV_DATA arg1) {
									int flags = 0;
									int t0 = Integer.parseInt(arg0.subcode);
									int t1 = Integer.parseInt(arg1.subcode);
									if (t0 < t1) {
										flags = -1;
									}else if(t0 > t1) {
										flags = 1;
									}else{
										flags = 0;
									}
									return flags;
								}
								
							});
							for(MULTI_USER_DEV_DATA d:temp){
								d.index = index;
								mAccountListData.add(d);
								if(mCurAccount.id.equals(d.id) && mCurAccount.subcode.equals(d.subcode)){
									foundsub = true;
									mCurAccount.index = index;
								}
								index ++;
							}
						}
					}
				}
				
				if(mAccountListData.size() > 0){
					if(foundsub == false){
						mCurAccount = mAccountListData.get(0);
					}
				}
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	private void buildCard(){
		if(mSlider == null)
			return;
		
		int size = mAccountListData.size();
		if(size <= 0){
			mSlider.setVisibility(View.GONE);
			mCardTitle.setVisibility(View.VISIBLE);
			return;
		}
	
		if(loaded){	
			mPages.clear();
			mFragmentMap.clear();
			mSlider.setVisibility(View.VISIBLE);
			mCardTitle.setVisibility(View.INVISIBLE);
			for(MULTI_USER_DEV_DATA d:mAccountListData){
				HealthCardFragment one = new HealthCardFragment(mApp);
				Bundle args = new Bundle();
				
				args.putInt("total", size);
				args.putSerializable("account", d);
				one.setArguments(args);
				mPages.add(one);
				mFragmentMap.put(d.id+"-"+d.subcode, one);
				if(d.id.equals(mCurAccount.id) && d.subcode.equals(mCurAccount.subcode)){
					one.queryHealthDataAndPower(mCurAccount.id, mCurAccount.subcode,false);
				}
			}
			mAdapter.notifyDataSetChanged();		
			mSlider.setCurrentItem(mCurAccount.index);
		}else{
			mPages.clear();
			mFragmentMap.clear();
			mSlider.setVisibility(View.GONE);
			mCardTitle.setVisibility(View.INVISIBLE);
		}
	}
	
	private final int MSG_LOADING_TIMEOUT = 221;
	
	private Handler mhandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			switch(msg.what){
			case MSG_LOADING_TIMEOUT:{
				loadingFinish();
			}break;
			}
		}
	};
	
	private void loadingFinish(){
		loaded = true;
		mhandler.removeMessages(MSG_LOADING_TIMEOUT);
		mLoadingProgress.setVisibility(View.GONE);
		buildCard();
	}
	
	private String[] getTids(){
		ArrayList<String> tidarr = new ArrayList<String>();
		String tid = "";
		for(DEV_DATA d:mAccountListData){
			if(tid.equals(d.id)){
				continue;
			}
			tid = new String(d.id);
			tidarr.add(tid);
		}
		
		int len = tidarr.size();
		if(len > 0){
			String[] tids = new String[len];
			tids = tidarr.toArray(tids);
			return tids;
		}
		
		return null;
	}
	
	private void startLoading(){
		int size = mAccountListData.size();
		if(size > 0){
			if(mApp.getDataManager().refreshData(DataManager.F_DEVICESUBINFO)){
				mLoadingProgress.setVisibility(View.VISIBLE);
				mLoadingProgress.setMax(size);
				mLoadingProgress.setProgress(0);
				//refresh.setVisibility(View.INVISIBLE);
				mhandler.removeMessages(MSG_LOADING_TIMEOUT);
				Message m = mhandler.obtainMessage(MSG_LOADING_TIMEOUT);
				mhandler.sendMessageDelayed(m, size * 10 * 1000);
				return;
			}
		}
		loadingFinish();
	}
	
	private void refreshDeviceSetting(){
		long upTime = mApp.getDataManager().checkRequestTime(DataManager.F_DEVICE_SETTINGS);
		long curMs = System.currentTimeMillis();
		if((curMs - upTime) < 1000 * 60 * 1){
			return;
		}
		
		String[] args = getTids();		
		if((args != null) && (args.length > 0)){
			mApp.getDataManager().setUserData(DataManager.F_DEVICE_SETTINGS, args);
			mApp.getDataManager().refreshData(DataManager.F_DEVICE_SETTINGS);
		}
	}
	
	private BroadcastReceiver mReceiver = new BroadcastReceiver(){
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if(action.equals(DataManager.DATA_UPDATE_ACTION)){
				String t = intent.getStringExtra("type");
				boolean s = intent.getBooleanExtra("state", false);				
				logd("onReceive:"+t+";"+s);
				if(t.equals(DataManager.F_DEVICESUBLIST)){
					if(s){
						refreshAccountList();
					}
				}else if(t.equals(DataManager.F_DEVICESUBINFO)){
					String tid = intent.getStringExtra("tid");
					String subcode = intent.getStringExtra("subcode");
					if(loaded == false){
						int max = mLoadingProgress.getMax();
						int pro = mLoadingProgress.getProgress();
						if(pro == max)
							return;
						
						pro += 1;
						mLoadingProgress.setProgress(pro);
						if(pro == max){
							loadingFinish();
						}
					}else{
						HealthCardFragment cf = mFragmentMap.get(tid+"-"+subcode);
						if(cf != null){
							cf.refreshResult(DataManager.F_DEVICESUBINFO,s);
						}else{
							//new sub
							refreshAccountList();
						}
					}
				}else if(t.equals(DataManager.F_DEVICE_SETTINGS)){
					//String tid = intent.getStringExtra("tid");
				}else if(t.equals(DataManager.F_DEVICE_POWER)){
					//String tids = intent.getStringExtra("tidarr");
				}else if(t.equals(DataManager.F_GLYCOSE_DATA)){
					String tid = intent.getStringExtra("tid");
					String subcode = intent.getStringExtra("subcode");
					boolean isFinish = intent.getBooleanExtra("isFinish", false);
					
						HealthCardFragment cf = mFragmentMap.get(tid+"-"+subcode);
						if(cf != null){
							cf.refreshResult(DataManager.F_GLYCOSE_DATA,isFinish);
						}

				}else if(t.equals(DataManager.F_GLYCOSE_SET)){
					mCurAccount = mAccountListData.get(mCurAccount.index);
					
					HealthCardFragment cf = mFragmentMap.get(mCurAccount.id + "-" + mCurAccount.subcode);
						if(cf != null){
							cf.refreshResult(DataManager.F_GLYCOSE_SET,s);
						}
				}else if(t.equals(DataManager.F_BP_DATA)){
					String tid = intent.getStringExtra("tid");
					String subcode = intent.getStringExtra("subcode");
					boolean isFinish = intent.getBooleanExtra("isFinish", false);
					
						HealthCardFragment cf = mFragmentMap.get(tid+"-"+subcode);
						if(cf != null){
							cf.refreshResult(DataManager.F_BP_DATA,isFinish);
						}

				}
			}
		}
	};
	
	@Override
	public void onSaveInstanceState(Bundle b){
		//must keep this override to avoid fragment leak
	}

	@Override
	public void onResume(){
		super.onResume();
		IntentFilter filter = new IntentFilter();
		filter.addAction(DataManager.DATA_UPDATE_ACTION);
		registerReceiver(mReceiver, filter);
		if(!loaded){
			startLoading();
		}else{
			refreshAccountList();
		}
	}
	
	@Override
	public void onPause(){
		super.onPause();
		logd("onPause");
		unregisterReceiver(mReceiver);
		mhandler.removeMessages(MSG_LOADING_TIMEOUT);
	}
	
	@Override
	public void onDestroy(){
		mPages.clear();
		mFragmentMap.clear();
		super.onDestroy();
	}
	
	private boolean curFragmentIsRefreshing(){
		HealthCardFragment cf = mFragmentMap.get(mCurAccount.id + "-" + mCurAccount.subcode);
		if(cf != null){
			return cf.isRefreshing();
		}
		return false;
	}
	
	private void stopRefreshing(){
		HealthCardFragment cf = mFragmentMap.get(mCurAccount.id + "-" + mCurAccount.subcode);
		if(cf != null){
			cf.cancelRefresh();
		}
	}
	
	@Override
    public boolean onKeyDown(int keyCode, KeyEvent event){
	   	
	   	if(keyCode == KeyEvent.KEYCODE_BACK){
	   		if(curFragmentIsRefreshing()){
	   			stopRefreshing();
	   			return true;
	   		}
	   	}
	   	return super.onKeyDown(keyCode,event);
    }
	
	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.back:{
			finish();
		}break;
		case R.id.set:{
			if(mAccountListData.size()>0){
				mCurAccount = mAccountListData.get(mCurAccount.index);
				Intent i = new Intent(this,SettingActivity.class);
				i.putExtra("from", "health_card");
				i.putExtra("dev", mCurAccount);
				startActivityForResult(i, RESULT_CODE_CARD_SETTINGS);
			}
		}break;
		}
		
	}
	
	private int RESULT_CODE_CARD_SETTINGS = 33;
	@Override
	public void onActivityResult(int code, int ret, Intent intent){
		if(RESULT_CODE_CARD_SETTINGS == code){
			if(ret == RESULT_OK){
				
				
			}
		}
	}

	@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPageSelected(int pos) {
		HealthCardFragment old_cf = mFragmentMap.get(mCurAccount.id + "-" + mCurAccount.subcode);
		old_cf.focusChange(false);
		mCurAccount = mAccountListData.get(pos);
		
		HealthCardFragment cf = mFragmentMap.get(mCurAccount.id + "-" + mCurAccount.subcode);
		cf.focusChange(true);
	}
	
}
